package com.secxiot.provider.task.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.jpush.api.push.PushResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.secxiot.common.constant.ServerStatusEnum;
import com.secxiot.common.constant.TaskEnum;
import com.secxiot.common.exception.BaseException;
import com.secxiot.common.exception.BaseRuntimeException;
import com.secxiot.common.utils.*;
import com.secxiot.consumer.user.feign.UserClient;
import com.secxiot.provider.system.vo.DataDictVo;
import com.secxiot.provider.task.dao.*;
import com.secxiot.provider.task.dto.*;
import com.secxiot.provider.task.entity.*;
import com.secxiot.provider.task.service.TaskService;
import com.secxiot.provider.task.vo.*;
import com.secxiot.provider.user.dto.UserDeptDto;
import com.secxiot.provider.user.entity.UserDo;
import com.secxiot.provider.user.vo.HospitalVo;
import com.secxiot.provider.user.vo.UserEmergencyContactVo;
import com.secxiot.provider.user.vo.UserSimpleVo;
import com.secxiot.provider.user.vo.WxAppVo;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.ibatis.annotations.Param;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.Period;
import java.time.ZoneId;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

@Transactional
@Service
public class TaskServiceImpl implements TaskService {

    private static Logger log = LoggerFactory.getLogger(TaskServiceImpl.class);
    /**
     * 交接
     */
    private final static String TASK_TRANSF = "0000200003";
    private final static Long TASK_TIME = 5 * 60 * 1000L;
    private final static Long TASK_SMS_TIME = 3 * 60 * 1000L;
    private final static String APP_ID = "西安救护车";
    private final static String APP_SIGNATURE = "365d740d60bc93c0ce613cb1e1f53281";

    @Autowired
    TaskDao taskDao;
    @Autowired
    TaskExecutionDao taskExecutionDao;
    @Autowired
    TaskFileDao taskFileDao;
    @Autowired
    TaskContentDao taskContentDao;
    @Autowired
    TaskTimeDao taskTimeDao;
    @Autowired
    TaskFileLogDao taskFileLogDao;
    @Autowired
    TaskTransferDao taskTransferDao;
    @Autowired
    UserClient userClient;
    @Autowired
    TaskTransferFileRelDao transferFileRelDao;
    @Autowired
    TaskPatientDataDao patientDataDao;
    @Autowired
    TaskAttributeTempMapper taskAttributeTempMapper;
    @Autowired
    TaskExecutionDeptDao taskExecutionDeptDao;
    @Autowired
    TaskAttributeTempDeptValueMapper taskAttributeTempDeptValueMapper;
    @Autowired
    SosReceiverDao sosReceiverDao;
    @Autowired
    TaskVisitRelDao taskVisitRelDao;
    @Autowired
    private TaskSenderDeptDao taskSenderDeptDao;

    @Autowired
    private TaskSOSDao taskSOSDao;

    @Autowired
    private JpushMsgDao jpushMsgDao;

    @Autowired
    private JpushLogDao jpushLogDao;

    @Autowired
    private SosDiseaseDao sosDiseaseDao;

    @Autowired
    IdWorker idWorker;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private MapConvertUtil mapConvertUtil;

    @Autowired
    private SosPositionRecordDao sosPositionRecordDao;

    @Autowired
    private RemindAmbulanceDao remindAmbulanceDao;

    @Autowired
    private CarGpsUtil carGpsUtil;

    @Override
    public TaskHomeVo listUnfinishedByUserIdAndTime(Long userId, Long pageNo, Long pageSize, Date since, Date last) {
        Date date = new Date();
        last = last == null ? date : last;
        TaskHomeVo home = new TaskHomeVo();
        home.setLast(last);
        home.setPageNo(pageNo);
        home.setPageSize(pageSize);
        home.setSince(since);
        home.setLast(last);
        //查询接收用户得任务
        List<TaskExecution> executions = taskExecutionDao.selectByReceiverIdAndTime(userId, pageNo, pageSize, since, last);
        if (CollectionUtils.isEmpty(executions)) {
            home.setTotal(0);
            home.setTasks(Collections.emptyList());
            return home;
        }
        long total = taskExecutionDao.countByReceiverIdAndTime(userId, since, last);
        home.setCount(executions.size());
        home.setTotal(total);
        // TODO
        List<TaskVo> taskVos = getTaskVos(executions);

        List<TaskVo> sosTaskList = new ArrayList<>();
        for (int i = 0; i < taskVos.size(); i++) {
            String taskType = taskVos.get(i).getTaskType();
            if ("0000200001".equals(taskType) || "0000200005".equals(taskType)) {
                sosTaskList.add(taskVos.remove(i));
            }
        }

        taskVos.addAll(0, sosTaskList);
        home.setTasks(taskVos);
        return home;
    }

    /**
     * 获取任务信息集合
     *
     * @param executions
     * @return
     */
    private List<TaskVo> getTaskVos(List<TaskExecution> executions) {
        List<Long> taskIds = executions.stream().map(e -> e.getTaskId()).collect(Collectors.toList());
        TaskExample example = new TaskExample();
        example.setOrderByClause("priority DESC, update_time DESC");
        example.createCriteria().andTaskIdIn(taskIds);
        List<Task> tasks = taskDao.selectByExample(example);
        //刨析时间段任务的数据拼装
        List<TaskVo> taskVos = new ArrayList<>();
        for (int s = 0; s < tasks.size(); s++) {
            Task task = tasks.get(s);
            String taskType = task.getTaskType();//任务类型
            Long taskId = task.getTaskId();//任务id
            TaskExecution execution = executions.stream().filter(e -> e.getTaskId().equals(taskId)).findFirst().get();
            Long executionId = execution.getId();
            TaskVo taskVo = new TaskVo();

            //任务时间
            TaskTimeExample taskTimeExample = new TaskTimeExample();
            taskTimeExample.createCriteria().andTaskIdEqualTo(taskId).andDelFlagEqualTo(0);
            TaskTime taskTime = taskTimeDao.selectByExample(taskTimeExample).get(0);

            //任务公共内容
            taskVo.setDelFlag(execution.getDelFlag());
            taskVo.setConfirmStatus(execution.getConfirmStatus());
            taskVo.setTaskTime(new Date(taskTime.getTaskTime()));
            taskVo.setConfirmRequired(task.getConfirmRequired());
            taskVo.setPriority(task.getPriority());
            taskVo.setSenderId(task.getSenderId());
            taskVo.setSenderName(task.getSenderName());
            taskVo.setTaskId(task.getTaskId());
            taskVo.setTaskType(task.getTaskType());
            taskVo.setUpdateTime(task.getUpdateTime());

            try {
                if (taskType.equals(TASK_TRANSF)) {
                    //交接类
                    List<TaskTransferVo> taskTransferVos = new ArrayList<>();
                    // 交接内容
                    TaskTransferExample transExam = new TaskTransferExample();
                    transExam.createCriteria().andTaskIdEqualTo(taskId);
                    List<TaskTransfer> taskTransfers = taskTransferDao.selectByExample(transExam);
                    List<Long> transferIds = taskTransfers.stream().map(t -> t.getId()).collect(Collectors.toList());

                    //患者数据
                    List<TaskPatientDataVo> pdvos = patientDataDao.selectByExectionId(executionId);

                    //交接文件
                    TaskTransferFileRelExample transferFileRelExamp = new TaskTransferFileRelExample();
                    transferFileRelExamp.createCriteria().andTransferIdIn(transferIds);
                    List<TaskTransferFileRel> transferFileRels = transferFileRelDao.selectByExample(transferFileRelExamp);

                    List<Long> transferFileRelIds = transferFileRels.stream().map(tfl -> tfl.getTaskFileId()).collect(Collectors.toList());
                    TaskFileExample taskFileExam = new TaskFileExample();
                    taskFileExam.createCriteria().andDelFlagEqualTo(0).andIdIn(transferFileRelIds);
                    List<TaskFile> taskFiles = CollectionUtils.isEmpty(transferFileRelIds) ? Collections.emptyList()
                            : taskFileDao.selectByExample(taskFileExam);
                    for (int i = 0; i < taskTransfers.size(); i++) {
                        TaskTransferVo transferVo = new TaskTransferVo();
                        TaskTransfer transfer = taskTransfers.get(i);
                        Long transferId = transfer.getId();//交接内容id
                        transferVo.setTransferId(transferId);//交接id
                        transferVo.setPatientId(transfer.getPatientId());//患者id
                        transferVo.setPatientName(transfer.getPatientName());//患者姓名
                        transferVo.setDiagnosis(transfer.getDiagnosis());//诊断
                        transferVo.setTransferContent(transfer.getTransferContent());//交接内容
                        //查出每个任务得附件关联
                        List<Long> transFL = transferFileRels.stream().filter(tfl -> tfl.getTransferId().equals(transferId))
                                .map(l -> l.getTaskFileId()).collect(Collectors.toList());
                        List<TaskFileVo> transFiles = taskFiles.stream().filter(f -> transFL.contains(f.getId())).map(f -> {
                            TaskFileVo taskFileVo = new TaskFileVo();
                            taskFileVo.setFileType(f.getFileType());
                            taskFileVo.setFileUri(f.getFileUri());
                            return taskFileVo;
                        }).collect(Collectors.toList());
                        transferVo.setFiles(transFiles);//附件

                        //患者数据
                        List<TaskPatientDataVo> patientDataVos = pdvos.stream().filter(
                                p -> p.getTransferId().equals(transferId)).collect(Collectors.toList());
                        transferVo.setPatientDatas(patientDataVos);//数据
                        taskTransferVos.add(transferVo);
                    }

                    taskVo.setTransfers(taskTransferVos);
                } else if (taskType.equals("0000200001") || taskType.equals("0000200005")) {
                    //接诊出诊
                    TaskSosVo taskSosVo = new TaskSosVo();

                    //sos
                    TaskSOS sos = taskSOSDao.selectByTaskId(taskId, null, null);
                    //BeanUtils.copyProperties(sos, taskSosVo);
                    CachedBeanCopier.copy(sos, taskSosVo);
                    taskSosVo.setPatientId(sos.getUserId());//患者id
                    taskSosVo.setPatientAddress(sos.getUserAddress());
/*                    taskSosVo.setPatientName(sos.getPatientName());//患者姓名
                    taskSosVo.setPatientMobile(sos.getPatientMobile());//患者电话
                    taskSosVo.setEmergencyMobile(sos.getEmergencyMobile());//紧急电话
                    taskSosVo.setEmergencyName(sos.getEmergencyName());//紧急联系人姓名
                    taskSosVo.setLongitude(sos.getLongitude());//患者经度
                    taskSosVo.setLatitude(sos.getLatitude());//患者纬度
                    taskSosVo.setPatientAddress(sos.getUserAddress());//患者地址
                    taskSosVo.setHospitalId(sos.getHospitalId());//医院id
                    taskSosVo.setHospitalLongitude(sos.getHospitalLongitude());//医院经度
                    taskSosVo.setHospitalLatitude(sos.getHospitalLatitude());//医院纬度
                    taskSosVo.setRemark(sos.getRemark());//出诊备注*/

                    //sos任务主体
                    taskVo.setSos(taskSosVo);
                } else {
                    //普通任务
                    //查出每个任务得附件
                    TaskFileExample fileExamp = new TaskFileExample();
                    fileExamp.createCriteria().andTaskIdEqualTo(taskId).andDelFlagEqualTo(0);
                    List<TaskFile> taskFiles = taskFileDao.selectByExample(fileExamp);
                    List<TaskFileVo> fileVos = new ArrayList<>();
                    if (taskFiles.size() > 0) {
                        for (int t = 0; t < taskFiles.size(); t++) {
                            TaskFileVo taskFileVo = new TaskFileVo();
                            taskFileVo.setFileUri(taskFiles.get(t).getFileUri());
                            taskFileVo.setFileType(taskFiles.get(t).getFileType());
                            fileVos.add(taskFileVo);
                        }
                    }
                    // 查询每个任务得正文
                    TaskContentExample contentExam = new TaskContentExample();
                    contentExam.createCriteria().andTaskIdEqualTo(taskId).andDelFlagEqualTo(0);
                    List<TaskContent> contents = taskContentDao.selectByExample(contentExam);
                    if (!CollectionUtils.isEmpty(contents)) {
                        taskVo.setContent(contents.get(0).getContent());
                    }

                    taskVo.setFiles(fileVos);
                }
                taskVos.add(taskVo);
            } catch (Exception e) {
                log.error("【任务查询异常】executionId:" + executionId);
                log.error(e.getMessage(), e);
            }
        }
        return taskVos;
    }

    //发布普通任务内容
    @Override
    public Long publish(TaskDto taskDto) {
        List<TaskExecutionDept> execDepts = new ArrayList<>();
        List<TaskExecution> executions = new ArrayList<>();
        List<TaskFile> taskFiles = new ArrayList<>();

        //创建任务表id
        Long taskId = idWorker.nextId();
        Long senderId = taskDto.getSenderId();
        UserDo user = userClient.getUser(senderId);
        @NotEmpty String senderName = taskDto.getSenderName();
        @NotEmpty String taskType = taskDto.getTaskType();
        Task task = new Task();
        task.setTaskId(taskId);//任务表id
        Date date = new Date();
        task.setCreateTime(date);//创建时间
        task.setUpdateTime(date);//修改时间
        task.setTaskType(taskType);//任务类型
        task.setSenderName(senderName);//发布人姓名
        task.setSenderId(senderId);//发布人id
        task.setPriority(taskDto.getPriority());//紧急程度
        task.setConfirmRequired(taskDto.getConfirmRequired());//是否需要确认
        //版本号和id一致
        task.setVersion(1L);
        task.setHospitalId(user.getHospitalId());
        //插入任务表数据
        taskDao.insert(task);

        //插入任务时间
        TaskTimeDto taskTimeDto = taskDto.getTaskTimeDto();
        Long timeId = idWorker.nextId();
        this.insertTaskTime(taskId, taskTimeDto, timeId);
        Date taskDateTime = new Date(taskTimeDto.getTaskTime());

        //接收者
        List<Long> receiverIds = taskDto.getReceiverIds();
        for (int i = 0; i < receiverIds.size(); i++) {
            Long receiverId = receiverIds.get(i);
            UserDo receiver = userClient.getUser(receiverId);
            List<UserDeptDto> reveiverDepts = null;
            if ("0000100001".equals(receiver.getType())) {
                reveiverDepts = userClient.listSupperDeptByUserId(senderId);
            } else {
                reveiverDepts = userClient.listSupperDeptByUserId(receiverId);
            }
            this.handleReciever(execDepts, executions, taskId, date, timeId, taskDateTime, receiverId, receiver.getName(), reveiverDepts, taskType);
        }

        //发送者部门
        List<UserDeptDto> senderDeptDtos = userClient.listSupperDeptByUserId(senderId);
        List<TaskSenderDept> senderDepts = this.getSenderDeptList(taskId, senderDeptDtos);

        //正文
        TaskContent taskContent = new TaskContent();
        taskContent.setContent(taskDto.getContent());
        Long contentId = idWorker.nextId();
        taskContent.setId(contentId);
        taskContent.setTaskId(taskId);
        taskContent.setVersion(1L);
        taskContentDao.insertSelective(taskContent);

        //添加任务附件
        List<TaskFileDto> fileDtos = taskDto.getFileIds();
        this.addTaskFileToList(taskFiles, taskId, fileDtos);

        taskExecutionDao.insertBatch(executions);
        taskSenderDeptDao.insertBatch(senderDepts);
        taskExecutionDeptDao.insertBatch(execDepts);
        //修改文件上传记录使用状态
        if (!CollectionUtils.isEmpty(taskFiles)) {
            taskFileDao.insertBatch(taskFiles);
            Long used = userClient.useFileLogs(
                    taskFiles.stream().map(f -> f.getFileLogId()).collect(Collectors.toList()));
        }
        return taskId;
    }

    /**
     * 转换发送者部门
     *
     * @param taskId
     * @param senderDeptDtos
     * @return
     */
    private List<TaskSenderDept> getSenderDeptList(Long taskId, List<UserDeptDto> senderDeptDtos) {
        return senderDeptDtos.stream().map(d -> {
            TaskSenderDept senderDept = new TaskSenderDept();
            senderDept.setId(idWorker.nextId());
            senderDept.setTaskId(taskId);
            senderDept.setDeptId(d.getDeptId());
            senderDept.setDirectFlag(d.getDirectFlag());
            return senderDept;
        }).collect(Collectors.toList());
    }

    /**
     * 处理接收者,将该任务的执行记录和执行记录部门添加到集合
     *
     * @param execDepts
     * @param executions
     * @param taskId
     * @param date
     * @param timeId
     * @param taskDateTime
     * @param receiverId
     * @param receiverName
     * @param reveiverDepts
     */
    private void handleReciever(List<TaskExecutionDept> execDepts, List<TaskExecution> executions, Long taskId, Date date,
                                Long timeId, Date taskDateTime, Long receiverId, String receiverName, List<UserDeptDto> reveiverDepts, String taskType) {
        Long execId = idWorker.nextId();
        this.addReceiverToList(executions, taskId, date, timeId, taskDateTime, receiverId, receiverName, execId, taskType);
        this.addReceiverDeptToList(execDepts, reveiverDepts, execId);

    }

    /**
     * 添加接收者部门到集合
     *
     * @param execDepts
     * @param reveiverDepts
     * @param execId
     */
    private void addReceiverDeptToList(List<TaskExecutionDept> execDepts, List<UserDeptDto> reveiverDepts, Long execId) {
        //加入任务部门表得数据
        for (int j = 0; !CollectionUtils.isEmpty(reveiverDepts) && j < reveiverDepts.size(); j++) {
            UserDeptDto userDeptDto = reveiverDepts.get(j);
            TaskExecutionDept exeDept = new TaskExecutionDept();
            exeDept.setId(idWorker.nextId());
            exeDept.setExecutionId(execId);
            exeDept.setDeptId(userDeptDto.getDeptId());
            exeDept.setDirectFlag(userDeptDto.getDirectFlag());
            execDepts.add(exeDept);
        }
    }

    /**
     * 添加任务文件到集合
     *
     * @param taskFiles
     * @param taskId
     * @param fileDtos
     */
    private void addTaskFileToList(List<TaskFile> taskFiles, Long taskId, List<TaskFileDto> fileDtos) {
        if (!CollectionUtils.isEmpty(fileDtos)) {
            for (TaskFileDto taskFileDto : fileDtos) {
                //任务附件
                Long fId = idWorker.nextId();
                TaskFile taskFile = new TaskFile();
                taskFile.setId(fId);
                taskFile.setTaskId(taskId);
                taskFile.setFileType(taskFileDto.getFileType());
                taskFile.setFileUri(taskFileDto.getFileUri());
                taskFile.setFileLogId(taskFileDto.getFileLogId());
                taskFile.setDelFlag(0);
                taskFiles.add(taskFile);
            }
        }
    }

    /**
     * 添加执行记录到集合List<TaskExecution>
     *
     * @param executions
     * @param taskId
     * @param date
     * @param timeId
     * @param taskDateTime
     * @param receiverId
     * @param receiverName
     * @param execId
     * @return
     */
    private TaskExecution addReceiverToList(List<TaskExecution> executions, Long taskId, Date date, Long timeId,
                                            Date taskDateTime, Long receiverId, String receiverName, Long execId, String taskType) {
        TaskExecution taskExecution = new TaskExecution();
        //任务执行表id
        taskExecution.setId(execId);
        //任务id
        taskExecution.setTaskId(taskId);
        //接收者id
        taskExecution.setReceiverId(receiverId);
        //未传入 接收者姓名和接收者类型
        taskExecution.setReceiverName(receiverName);
        //传入未推送
        taskExecution.setSendFlag("0");
        //时间表id
        taskExecution.setTaskTimeId(timeId);
        //任务完成时间
        taskExecution.setTaskTime(taskDateTime);//时间
        //当前循环次数
        taskExecution.setCycleCount(1);
        //任务执行状态
        taskExecution.setConfirmStatus("0000800001");
        //确认时间
        taskExecution.setConfirmTime(date);//待定当前时间
        taskExecution.setDelFlag(0);
        taskExecution.setTaskType(taskType);
        taskExecution.setReportLocation(0);
        executions.add(taskExecution);
        return taskExecution;
    }

    /**
     * 插入任务时间
     *
     * @param taskId      任务id
     * @param taskTimeDto 前台接收的任务时间
     * @param timeId      时间id
     * @return 插入数量
     */
    private int insertTaskTime(Long taskId, TaskTimeDto taskTimeDto, Long timeId) {
        //单次周期
        if (taskTimeDto.getTimeType().equals("0000400001")) {
            TaskTime taskTime = new TaskTime();
            //插入id
            taskTime.setId(timeId);
            taskTime.setTaskId(taskId);
            //时间
            taskTime.setTaskTime(taskTimeDto.getTaskTime());
            //类型
            taskTime.setTimeType(taskTimeDto.getTimeType());
            taskTime.setEndTime(new Date(taskTimeDto.getTaskTime()));//结束时间定义为当前时间
            taskTime.setCycleType("-1");
            //循环次数
            taskTime.setCycleCount(1);
            taskTime.setDelFlag(0);
            taskTime.setVersion(1L);
            return taskTimeDao.insertSelective(taskTime);
        } else {
            log.info("任务时间类型暂不支持，timeType:" + taskTimeDto.getTimeType());
            return 0;
        }
    }

    /**
     * 交接任务
     *
     * @param taskTransferListDto 交接任务内容
     * @return
     */
    @Override
    public Long publishTransfer(TaskTransferListDto taskTransferListDto) {
        List<TaskExecutionDept> execDepts = new ArrayList<>();
        List<TaskExecution> executions = new ArrayList<>();
        List<TaskFile> taskFiles = new ArrayList<>();
        Date date = new Date();

        Task task = new Task();
        //任务id
        Long taskId = idWorker.nextId();
        @NotEmpty Long senderId = taskTransferListDto.getSenderId();
        UserDo sender = userClient.getUser(senderId);
        //任务主表
        task.setTaskId(taskId);//任务id
        task.setHospitalId(sender.getHospitalId());
        task.setTaskType(taskTransferListDto.getTaskType());//交接任务类型
        task.setSenderId(senderId);//交接人id
        task.setSenderName(taskTransferListDto.getSenderName());//交接人名称
        task.setPriority("0000300001");//紧急程度
        task.setConfirmRequired(1);//是否确认
        task.setCreateTime(date);//创建任务时间
        task.setUpdateTime(date);//修改时间
        task.setVersion(1L);//版本号
        taskDao.insertSelective(task);

        //插入任务时间
        TaskTimeDto taskTimeDto = taskTransferListDto.getTaskTimeDto();
        Long timeId = idWorker.nextId();//时间id
        this.insertTaskTime(taskId, taskTimeDto, timeId);
        Date taskDateTime = new Date(taskTimeDto.getTaskTime());

        //接收者
        List<Long> receiverIds = taskTransferListDto.getReceiverIds();
        for (Long receiverId : receiverIds) {
            UserDo receiver = userClient.getUser(receiverId);
            if ("0000100001".equals(receiver.getType())) {
                throw new BaseRuntimeException(ServerStatusEnum.RECEIVER_DATA_EXCEPTION);
            }
            List<UserDeptDto> reveiverDepts = userClient.listSupperDeptByUserId(receiverId);

            this.handleReciever(execDepts, executions, taskId, date, timeId, taskDateTime, receiverId, receiver.getName(), reveiverDepts, taskTransferListDto.getTaskType());
        }

        //发送者部门
        List<UserDeptDto> senderDeptDtos = userClient.listSupperDeptByUserId(senderId);
        List<TaskSenderDept> senderDepts = this.getSenderDeptList(taskId, senderDeptDtos);

        //交接患者
        List<TaskTransferDto> transferDtos = taskTransferListDto.getTransfers();
        for (int i = 0; i < transferDtos.size(); i++) {
            TaskTransferDto transferDto = transferDtos.get(i);

            //交接内容
            TaskTransfer taskTransfer = new TaskTransfer();
            Long taskTransferId = idWorker.nextId();
            taskTransfer.setId(taskTransferId);//交接内容id
            taskTransfer.setTaskId(taskId);//任务id
            taskTransfer.setPatientId(transferDto.getPatientId());//患者id
            taskTransfer.setPatientName(transferDto.getPatientName());//患者姓名
            taskTransfer.setDiagnosis(transferDto.getDiagnosis());//诊断
            taskTransfer.setTransferContent(transferDto.getTransferContent());//内容
            taskTransfer.setBeds(transferDto.getBeds());
            taskTransferDao.insertSelective(taskTransfer);

            //添加任务附件
            List<TaskFileDto> fileDtos = transferDto.getFileIds();
            if (!CollectionUtils.isEmpty(fileDtos)) {
                for (TaskFileDto taskFileDto : fileDtos) {
                    //任务附件
                    Long fId = idWorker.nextId();
                    TaskFile taskFile = new TaskFile();
                    taskFile.setId(fId);
                    taskFile.setTaskId(taskId);
                    taskFile.setFileType(taskFileDto.getFileType());
                    taskFile.setFileUri(taskFileDto.getFileUri());
                    taskFile.setFileLogId(taskFileDto.getFileLogId());
                    taskFile.setDelFlag(0);
                    taskFiles.add(taskFile);

                    //交接附件关联
                    Long fileRelId = idWorker.nextId();
                    TaskTransferFileRel taskTransferFileRel = new TaskTransferFileRel();
                    taskTransferFileRel.setId(fileRelId);//交接id
                    taskTransferFileRel.setTaskFileId(fId);//交接内容表id
                    taskTransferFileRel.setTransferId(taskTransferId);//附件id
                    transferFileRelDao.insertSelective(taskTransferFileRel);
                }
            } else {
                log.info("患者：" + transferDto.getPatientId() + transferDto.getPatientName() + ",无附件");
            }

            //患者数据
            List<TaskPatientDataDto> patientDataDtos = transferDto.getPatientDatas();//患者数据集合
            Long patientDataId = idWorker.nextId();
            for (int t = 0; t < patientDataDtos.size(); t++) {
                TaskPatientDataDto taskPatientDataDto = patientDataDtos.get(t);
                TaskPatientData taskPatientData = new TaskPatientData();
                taskPatientData.setId(patientDataId);//患者数据id
                taskPatientData.setTransferId(taskTransferId);//交接内容id
                taskPatientData.setTempId(taskPatientDataDto.getTempId());//模板得id
                taskPatientData.setTempValue(taskPatientDataDto.getTempValue());//模板得值
                patientDataDao.insert(taskPatientData);
                patientDataId++;
            }
        }
        taskExecutionDao.insertBatch(executions);
        taskSenderDeptDao.insertBatch(senderDepts);
        taskExecutionDeptDao.insertBatch(execDepts);
        //修改文件上传记录使用状态
        if (!CollectionUtils.isEmpty(taskFiles)) {
            taskFileDao.insertBatch(taskFiles);
            Long used = userClient.useFileLogs(
                    taskFiles.stream().map(f -> f.getFileLogId()).collect(Collectors.toList()));
        }
        return taskId;
    }

    @Override
    public List<TaskAttributeTempDeptValue> TaskAttributeTempDeptValue(Long deptId) {
        if (deptId == null) {
            throw new BaseRuntimeException(ServerStatusEnum.NOT_FOUND);
        }
        List<TaskAttributeTempDeptValue> taskAttributeTempDeptValues = taskAttributeTempDeptValueMapper.selectTaskAttributeTempDeptValue(deptId);
        return taskAttributeTempDeptValues;
    }

    /**
     * 发布sos 任务
     *
     * @param taskSosDto
     * @return
     */
    @Override
    public Long publishSosTask(TaskSosDto taskSosDto) throws BaseException {
        List<TaskExecutionDept> execDepts = new ArrayList<>();
        List<TaskExecution> executions = new ArrayList<>();
        //发布人id
        Long senderId = taskSosDto.getSenderId();
        TaskSOSStatusVo status = this.getSOSTaskStatusByPatientId(senderId, null);
        if (status != null && "0000800001|0000800002|0000800003|0000800004|0000800010|0000800011|0000800012".contains(status.getConfirmStatus())) {
            throw new BaseRuntimeException(ServerStatusEnum.SOS_NOT_COMPLETE);
        }
        UserDo sender = userClient.getUser(senderId);
        if (StringUtils.isEmpty(taskSosDto.getWxAppId())) {
            throw new BaseRuntimeException(ServerStatusEnum.SOS_APP_ID_NULL);
        }

        WxAppVo wxApp = userClient.getWxApp(taskSosDto.getWxAppId());
        if (null == wxApp || wxApp.getStatus() != 1) {
            throw new BaseRuntimeException(ServerStatusEnum.APP_NULL);
        }

        @NotNull BigDecimal longitude = taskSosDto.getLongitude();
        @NotNull BigDecimal latitude = taskSosDto.getLatitude();

        //插入任务
        Long taskId = idWorker.nextId();
        Task task = new Task();
        String taskType = "0000200001";
        task.setTaskId(taskId);//任务表id
        Date date = new Date();
        task.setCreateTime(date);//创建时间
        task.setUpdateTime(date);//修改时间
        task.setTaskType(taskType);//任务类型
        task.setSenderName(sender.getName());//发布人姓名
        task.setSenderId(senderId);//发布人id
        task.setPriority("0000300003");//紧急程度
        task.setConfirmRequired(0);//是否需要确认
        task.setVersion(1L);

        //插入任务时间
        Long timeId = idWorker.nextId();//时间id
        TaskTime taskTime = new TaskTime();
        taskTime.setId(timeId);
        taskTime.setTaskId(taskId);//任务id
        taskTime.setTaskTime(date.getTime());//任务时间
        taskTime.setTimeType("0000400001");//时间类型
        taskTime.setEndTime(date);
        taskTime.setCycleCount(1);//默认1
        taskTime.setCycleType("-1");//周期类型
        taskTime.setDelFlag(0);//未删除
        taskTime.setVersion(1L);//版本号
        taskTimeDao.insertSelective(taskTime);

        List<HospitalVo> hospitals = new ArrayList<HospitalVo>();
        if (StringUtils.isEmpty(wxApp.getHospitalId())) {
            hospitals = userClient.listHospitalsByUser(senderId, longitude, latitude, "");
        } else {
            HospitalVo hospital = userClient.getHospitalById(wxApp.getHospitalId());
            hospitals.add(hospital);
        }

        /**/
        UserSimpleVo doctor = null;
        HospitalVo hospital = new HospitalVo();
        for (int i = 0; i < hospitals.size(); i++) {
            hospital = hospitals.get(i);
            List<UserSimpleVo> doctors = userClient.listHospitalSOSDoctor(hospital.getHospitalId(), null, taskType);
            if (!CollectionUtils.isEmpty(doctors)) {
                doctor = doctors.get(0);
                break;
            } else {
                log.info("医院id：" + hospital.getHospitalId() + ", 名称：" + hospital.getHospitalName() + "目前无SOS正在值班的接诊医生");
                if (i == hospitals.size() - 1) {
                    throw new BaseRuntimeException(ServerStatusEnum.NO_SOS_RECEIVER);
                }
            }
        }

        //执行记录
        Long receiverId = doctor.getUserId();//只根据医院id 查询的接收者
        Long execId = idWorker.nextId();
        this.addReceiverToList(executions, taskId, date, timeId, date, receiverId, doctor.getName(), execId, taskType);

        //接受者部门
        List<UserDeptDto> receiverDeptDtos = userClient.listSupperDeptByUserId(receiverId);
        this.addReceiverDeptToList(execDepts, receiverDeptDtos, execId);

        //发送者部门
        List<UserDeptDto> senderDeptDtos = receiverDeptDtos;
        List<TaskSenderDept> senderDepts = this.getSenderDeptList(taskId, senderDeptDtos);
        //腾讯经纬度转换为百度经纬度
        Map<String, Double> map = mapConvertUtil.map_tx2bd(latitude.doubleValue(), longitude.doubleValue());
        //SOS位置
        Long taskSosDoId = idWorker.nextId();
        TaskSOS taskSOS = new TaskSOS();
        taskSOS.setId(taskSosDoId);//taskId
        taskSOS.setTaskId(taskId);//任务id
        taskSOS.setHospitalId(hospital.getHospitalId());
        taskSOS.setHospitalName(hospital.getHospitalName());
        taskSOS.setHospitalLongitude(hospital.getLongitude());
        taskSOS.setHospitalLatitude(hospital.getLatitude());
        taskSOS.setUserAddress(taskSosDto.getAddress());
        taskSOS.setUserId(taskSosDto.getSenderId());
        taskSOS.setPatientName(sender.getName());
        taskSOS.setPatientMobile(sender.getMobile());
        taskSOS.setLongitude(new BigDecimal(map.get("lng") + ""));
        taskSOS.setLatitude(new BigDecimal(map.get("lat") + ""));
        taskSOS.setRemark(taskSosDto.getDiagnosis());
        taskSOS.setCreateTime(new Date());
        //增加医院ID
        task.setHospitalId(hospital.getHospitalId());

        //紧急联系人
        UserEmergencyContactVo contact = userClient.getContact(senderId);
        if (contact != null) {
            taskSOS.setEmergencyId(contact.getId());
            taskSOS.setEmergencyRelationship(contact.getRelationship());
            taskSOS.setEmergencyMobile(contact.getMobile());
            taskSOS.setEmergencyName(contact.getName());
        } else {
            log.info("患者用户id:" + senderId + ",姓名：" + sender.getName() + "，无紧急联系人");
        }

        taskDao.insert(task);
        taskSOSDao.insertSelective(taskSOS);
        taskExecutionDao.insertBatch(executions);
        taskSenderDeptDao.insertBatch(senderDepts);
        taskExecutionDeptDao.insertBatch(execDepts);

        try {
            Map<String, String> smsMap = new HashMap<String, String>();
            smsMap.put("name", sender.getName());
            smsMap.put("phone", sender.getMobile());
            smsMap.put("address", taskSosDto.getAddress());
            //JSMSUtil.sendTempSMS(doctor.getMobile(), 182621, smsMap);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return taskId;
    }

    @Override
    public int UpdateTaskUserPlace(TaskExecution taskExecution) {

        return taskExecutionDao.updateByPrimaryKeySelective(taskExecution);
    }

    @Override
    public TaskStatusVo getStatusById(Long taskId, Long userId) throws BaseException {

        TaskExecutionExample example = new TaskExecutionExample();
        example.createCriteria().andTaskIdEqualTo(taskId).andReceiverIdEqualTo(userId);
        List<TaskExecution> executions = taskExecutionDao.selectByExample(example);
        if (CollectionUtils.isEmpty(executions)) {
            throw new BaseException(ServerStatusEnum.TASK_NOT_EXIST);
        }
        TaskExecution taskExecution = executions.get(0);
        Task task = taskDao.selectByPrimaryKey(taskId);//任务表
        TaskStatusVo taskStatusVo = new TaskStatusVo();
        taskStatusVo.setTaskId(taskExecution.getTaskId());//任务id
        taskStatusVo.setConfirmStatus(taskExecution.getConfirmStatus());//状态
        taskStatusVo.setDelFlag(taskExecution.getDelFlag());//伪删除
        taskStatusVo.setUpdateTime(task.getUpdateTime());//修改时间
        return taskStatusVo;
    }

    @Override
    public TaskSOSStatusVo getSOSTaskStatusByPatientId(Long userId, Long taskId) throws BaseException {
        UserDo user = userClient.getUser(userId);
        TaskSOSStatusVo statusVo = null;
        if ("0000100001".equals(user.getType())) {
            statusVo = taskSOSDao.selectLastStatusByUserId(userId);
        } else {
            if (taskId == null) {
                throw new BaseException(ServerStatusEnum.PARAM_WRONG);
            }
            statusVo = taskSOSDao.selectStatusByUserIdAndTaskId(userId, taskId);
        }
        return statusVo;
    }

    /**
     * 发布出诊任务
     *
     * @param visitDto 出诊任务
     * @return
     */
    @Override
    public Long publishSosVisit(TaskVisitDto visitDto) throws BaseException {
        Long sosTaskId = visitDto.getSosTaskId();//任务id
        TaskSOS taskSOS = taskSOSDao.selectByTaskId(sosTaskId, "0000800004", "0000200001");
        if (taskSOS == null) {
            throw new BaseRuntimeException(ServerStatusEnum.TASK_VISIT);
        }
        Long senderId = visitDto.getSenderId();//发送者id  接诊人员
        String senderName = visitDto.getSenderName();

        String remark = visitDto.getRemark();//出诊备注
        List<SosDeptFacilityDto> facilityDtos = visitDto.getSosDeptFacilityDtos();//选取的设备集合
        //拼接设备remark到备注
        StringBuilder sb = new StringBuilder();
        if (!CollectionUtils.isEmpty(facilityDtos)) {
            for (int i = 0; i < facilityDtos.size(); i++) {
                String facilityName = facilityDtos.get(i).getFacilityName();//设备名称
                sb.append(facilityName);
                if (i < facilityDtos.size() - 1) {
                    sb.append("、");
                }
            }
        }
        sb.append("#").append(remark);

        List<TaskReceiverDto> taskReceiverDtoList = visitDto.getTaskReceiverDto();
        if (taskReceiverDtoList.size() <= 0) {
            throw new BaseRuntimeException(ServerStatusEnum.TASK_NOT_RECEIVER);
        }

        for (TaskReceiverDto taskReceiverDto : taskReceiverDtoList) {
            List<TaskExecutionDept> execDepts = new ArrayList<>();
            List<TaskExecution> executions = new ArrayList<>();

            Long receiverId = taskReceiverDto.getUserId();//接收者id  出诊人员
            List<TaskStatusVo> taskStatusVoList = taskDao.getTaskByReceiverId(receiverId);
            if (!CollectionUtils.isEmpty(taskStatusVoList)) {
                throw new BaseRuntimeException(ServerStatusEnum.TASK_NOT_COMPLETE);
            }

            String receiverName = taskReceiverDto.getName();

            Long taskId = idWorker.nextId();
            Task task = new Task();
            //创建任务表id
            task.setTaskId(taskId);//任务表id
            Date date = new Date();
            task.setCreateTime(date);//创建时间
            task.setHospitalId(taskSOS.getHospitalId());
            task.setUpdateTime(date);//修改时间
            task.setTaskType("0000200005");//任务类型
            task.setSenderName(senderName);//发布人姓名
            task.setSenderId(visitDto.getSenderId());//发布人id
            task.setPriority("0000300003");//紧急程度
            task.setConfirmRequired(1);//是否需要确认
            task.setVersion(1L);
            taskDao.insert(task);

            //时间
            Long timeId = idWorker.nextId();//时间id
            TaskTime taskTime = new TaskTime();
            taskTime.setId(timeId);
            taskTime.setTaskId(taskId);//任务id
            taskTime.setTaskTime(date.getTime());//任务时间
            taskTime.setTimeType("0000400001");//时间周期类型
            taskTime.setEndTime(date);
            taskTime.setCycleCount(1);//默认1
            taskTime.setCycleType("-1");//周期类型
            taskTime.setDelFlag(0);//未删除
            taskTime.setVersion(1L);//版本号
            taskTimeDao.insertSelective(taskTime);

            UserDo receiver = userClient.getUser(receiverId);
            List<UserDeptDto> reveiverDepts = userClient.listSupperDeptByUserId(receiverId);
            this.handleReciever(execDepts, executions, taskId, date, timeId, date, receiverId, receiverName, reveiverDepts, task.getTaskType());

            //发送者部门
            List<UserDeptDto> senderDeptDtos = userClient.listSupperDeptByUserId(senderId);
            List<TaskSenderDept> senderDepts = this.getSenderDeptList(taskId, senderDeptDtos);

            //SOS出诊
            TaskSOS visitSOS = new TaskSOS();
            Long visitSOSId = idWorker.nextId();
            BeanUtils.copyProperties(taskSOS, visitSOS);
            visitSOS.setId(visitSOSId);//taskId
            visitSOS.setTaskId(taskId);//任务id
            visitSOS.setRemark(sb.toString());//出诊备注
            visitSOS.setHospitalName(taskSOS.getHospitalName());
            taskSOSDao.insertSelective(visitSOS);

            //关联出诊接诊
            Long visitRelId = idWorker.nextId();
            TaskVisitRelDo taskVisitRelDo = new TaskVisitRelDo();
            taskVisitRelDo.setId(visitRelId);
            taskVisitRelDo.setTaskId(taskId);//出诊任务id
            taskVisitRelDo.setSosTaskId(sosTaskId);//接诊任务id
            taskVisitRelDao.insertTaskVisitRelDo(taskVisitRelDo);
            taskExecutionDao.insertBatch(executions);

            taskSenderDeptDao.insertBatch(senderDepts);
            taskExecutionDeptDao.insertBatch(execDepts);
        }

        //修改接诊人状态为待出诊
        updateStatus(senderId, sosTaskId, "0000800011");

        try {
            UserDo senderUser = userClient.getUser(senderId);
            Map<String, String> smsMap = new HashMap<String, String>();
            smsMap.put("name", senderUser.getName());
            smsMap.put("phone", senderUser.getMobile());
            smsMap.put("dname", taskSOS.getPatientName());
            smsMap.put("dphone", taskSOS.getPatientMobile());
            smsMap.put("address", taskSOS.getUserAddress());
            //JSMSUtil.sendTempSMS(receiver.getMobile(), 182622, smsMap);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return sosTaskId;
    }

    /**
     * 获取患者检测数据模版
     *
     * @param deptId 部门id
     * @return 患者检测数据模版列表
     */
    @Override
    public List<TaskTempVo> getTaskTemp(Long deptId) {
        return taskAttributeTempMapper.selectTaskAttributeTemp(deptId);
    }

    /**
     * 更新任务状态信息
     *
     * @param userId        用户id
     * @param taskId        任务id
     * @param confirmStatus 状态
     * @return 任务状态信息
     * @throws BaseException
     */
    @Override
    public TaskStatusUpdateVo updateStatus(Long userId, Long taskId, String confirmStatus) throws BaseException {
        TaskExecution execution = null;
        Date date = new Date();
        if ("0000800004".equals(confirmStatus) || "0000800007".equals(confirmStatus) || "0000800011".equals(confirmStatus)) {//接诊&取消
            TaskExecutionExample example = new TaskExecutionExample();
            example.createCriteria().andTaskIdEqualTo(taskId).andReceiverIdEqualTo(userId);
            List<TaskExecution> executions = taskExecutionDao.selectByExample(example);
            if (CollectionUtils.isEmpty(executions)) {
                throw new BaseException(ServerStatusEnum.TASK_NOT_EXIST);
            }
            execution = executions.get(0);
        } else {
            TaskExecutionExample example = new TaskExecutionExample();
            example.createCriteria().andTaskIdEqualTo(taskId);
            List<TaskExecution> executions = taskExecutionDao.selectByExample(example);
            if (CollectionUtils.isEmpty(executions)) {
                throw new BaseException(ServerStatusEnum.TASK_NOT_EXIST);
            }
            execution = executions.get(0);
            userId = execution.getReceiverId();
        }

        TaskStatusVo statusVo = taskDao.selectStatusById(userId, taskId);
        String original = execution.getConfirmStatus();
        TaskStatusUpdateVo updateVo = new TaskStatusUpdateVo();
        updateVo.setIsReportLocation(1);
        if (original.compareTo("0000800004") < 0) {
            if ("0000800004|0000800005|0000800006|0000800007|0000800011|0000800012|0000800013".contains(confirmStatus)) {
                List<TaskExecution> taskVisit = new ArrayList<TaskExecution>();
                if ("0000200005".equals(execution.getTaskType())) {
                    taskVisit = taskExecutionDao.getTaskExecutionVisit(execution.getTaskId());
                    for (TaskExecution taskExecution : taskVisit) {
                        if (confirmStatus.equals("0000800004") && taskExecution.getConfirmStatus().equals("0000800004")) {
                            updateVo.setIsReportLocation(0);
                            break;
                        }
                    }

                    if (updateVo.getIsReportLocation() > 0) {
                        execution.setReportLocation(1);
                        for (TaskExecution taskExecution : taskVisit) {
                            if (!taskExecution.getId().equals(execution.getId())) {
                                taskExecution.setReportLocation(0);
                                taskExecution.setConfirmStatus(confirmStatus);
                                taskExecutionDao.updateByPrimaryKey(taskExecution);
                            }
                        }
                    }
                }
                execution.setConfirmStatus(confirmStatus);
                taskExecutionDao.updateByPrimaryKey(execution);
                if ("0000200005".equals(execution.getTaskType())) {
                    List<TaskExecution> taskExecutionVisit = taskExecutionDao.getTaskExecutionVisit(execution.getTaskId());
                    boolean trueStr = true;
                    for (TaskExecution taskExecution : taskExecutionVisit) {
                        if (confirmStatus.equals("0000800004") && !taskExecution.getConfirmStatus().equals("0000800004")) {
                            trueStr = false;
                            break;
                        }
                    }

                    if (trueStr) {
                        List<TaskExecution> taskExecutionByParam = taskExecutionDao.getTaskExecutionByParam(execution.getTaskId(), execution.getTaskType());
                        for (TaskExecution taskExecu : taskExecutionByParam) {
                            if (confirmStatus.equals("0000800004")) {
                                taskExecu.setConfirmStatus("0000800012");
                            } else {
                                taskExecu.setConfirmStatus(confirmStatus);
                            }
                            taskExecu.setConfirmTime(date);
                            taskExecutionDao.updateByPrimaryKey(taskExecu);
                        }
                    }
                }

                statusVo.setConfirmStatus(confirmStatus);
                log.info("更新任务成功：{} ,状态：{}", taskId, confirmStatus);
            }

        } else if (original.equals("0000800010") && confirmStatus.equals("0000800005")) { //定时取消
            execution.setConfirmStatus(confirmStatus);
            execution.setConfirmTime(date);
            taskExecutionDao.updateByPrimaryKey(execution);
            statusVo.setConfirmStatus(confirmStatus);
            log.info("更新SOS任务成功：{} ,状态：{}", taskId, confirmStatus);

        } else if (!original.equals("0000800010") && original.compareTo("0000800004") >= 0) {
            if ("0000800011|0000800012".contains(confirmStatus)) {
                execution.setConfirmStatus(confirmStatus);
                execution.setConfirmTime(date);
                taskExecutionDao.updateByPrimaryKey(execution);
                statusVo.setConfirmStatus(confirmStatus);
                log.info("更新SOS任务成功：{} ,状态：{}", taskId, confirmStatus);

            } else if (!("0000800006|0000800007|0000800013").contains(original) && "0000800006|0000800007|0000800013".contains(confirmStatus)) {
                execution.setConfirmStatus(confirmStatus);
                execution.setConfirmTime(date);
                taskExecutionDao.updateByPrimaryKey(execution);
                statusVo.setConfirmStatus(confirmStatus);
                log.info("更新SOS任务成功：{} ,状态：{}", taskId, confirmStatus);

                String key = "SOS_" + execution.getTaskId();
                Object object = redisUtil.get(key);
                if (null != object) {
                    JSONObject obj = JSONObject.parseObject(object.toString());
                    obj.put("isReport", "false");
                    redisUtil.set(key, obj.toString(), 10 * 60);
                }

                List<TaskExecution> taskExecutionList = taskExecutionDao.getTaskExecutionByParam(execution.getTaskId(), execution.getTaskType());
                for (TaskExecution taskExecutionByParam : taskExecutionList) {
                    taskExecutionByParam.setConfirmStatus(confirmStatus);
                    taskExecutionByParam.setConfirmTime(date);
                    taskExecutionDao.updateByPrimaryKey(taskExecutionByParam);
                }

                List<TaskExecution> taskExecutionVisit = taskExecutionDao.getTaskExecutionVisit(taskId);
                for (TaskExecution taskExecution : taskExecutionVisit) {
                    if (taskExecution.getReportLocation() == 1) {
                        RemindAmbulanceVo remindAmbulanceVo = remindAmbulanceDao.getAmbulanceVoByTaskId(taskExecution.getTaskId());
                        remindAmbulanceVo.setTaskStatus(0);
                        remindAmbulanceDao.updateByPrimaryKeySelective(remindAmbulanceVo);
                    }
                }
            }
        } else {
            updateVo.setSuccess(false);
            log.info("更新任务失败：{} ,状态：{}", taskId, confirmStatus);
        }
        updateVo.setTaskStatusVo(statusVo);

        //发短信通知
        TaskSosVo taskSosVo = taskSOSDao.selectSosByTaskId(taskId);
        //"0000800004|0000800007|0000800010|0000800013".contains(confirmStatus)
        if (null != taskSosVo && "0000800012".equals(confirmStatus)) {
            if ("0000200005".equals(execution.getTaskType()) && "0000800004".equals(confirmStatus)) {
                confirmStatus = "0000800012";
            }
            List<DataDictVo> dataDictVos = userClient.listDataDict(confirmStatus);
            String dictValue = dataDictVos.get(0).getValue();
            if (confirmStatus.equals("0000800004")) {
                dictValue = "已接诊";
            }
            try {
                Map<String, String> map = new HashMap<>();
                map.put("status", dictValue);
                map.put("datetime", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
                map.put("hospital", taskSosVo.getHospitalName());
                //sendTempSMS(taskSosVo.getPatientMobile(), 182351, map);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }

        return updateVo;
    }

    /**
     * 极光推送定时任务
     *
     * @return
     */
    @Override
    public Integer pushPublishNotice() {
        Date date = new Date();
        TaskExecutionExample example = new TaskExecutionExample();
        example.createCriteria().andConfirmStatusEqualTo("0000800001").andDelFlagEqualTo(0);
        List<TaskExecution> executions = taskExecutionDao.selectByExample(example);
        if (CollectionUtils.isEmpty(executions)) {
            return 0;
        }
        List<TaskVo> taskVos = this.getTaskVos(executions);
        executions = executions.stream().collect(
                Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(e -> e.getTaskId() + ";" + e.getId()))), ArrayList::new)
        );
        Map<Long, List<TaskExecution>> execMap = executions.stream()
                .sorted((e1, e2) -> e1.getTaskId().compareTo(e2.getTaskId()))
                .collect(Collectors.groupingBy(e -> e.getTaskId()));
        for (int i = 0; i < taskVos.size(); i++) {
            TaskVo vo = taskVos.get(i);
            List<TaskExecution> es = execMap.get(vo.getTaskId());
            List<String> res = es.stream().map(e -> e.getReceiverId().toString()).collect(Collectors.toList());
            String[] resArray = res.toArray(new String[]{});
            HashMap<String, String> extras = new HashMap<>();
            extras.put("task", JSON.toJSONString(vo));
            extras.put("eventType", "0001000001");
            try {
                log.error("**********************************************推送任务开始***********************************************");
                log.error("******" + resArray.toString());
                String typeValue = TaskEnum.getByCode(vo.getTaskType()).value;
                JPushUtil.JsendLog jsendLog = JPushUtil.sendPush("医助手任务提醒", "您有新的" + typeValue + "任务，请打开医助手软件查看", extras, resArray);
                PushResult result = (PushResult) jsendLog.result;
                log.error(result.toString());
                log.error("**********************************************推送任务结束***********************************************");
                if (result.isResultOK()) {
                    for (int j = 0; j < es.size(); j++) {
                        TaskExecution e = new TaskExecution();
                        e.setId(es.get(j).getId());
                        e.setConfirmStatus("0000800003");
                        taskExecutionDao.updateByPrimaryKeySelective(e);
                    }
                }
                insertTaskPushLog(vo.getTaskId(), "0001000001", vo, resArray, result);

            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
        return executions.size();
    }

    private void insertTaskPushLog(Long taskId, String event, Serializable vo, String[] resArray, PushResult result) {
        List<JpushLog> jpushLogs = new ArrayList<>();
        List<JpushMsg> jpushMsgs = new ArrayList<>();
        Date date = new Date();
        JpushMsg jpushMsg = new JpushMsg();
        Long msPri = idWorker.nextId();
        jpushMsg.setId(msPri);
        jpushMsg.setMsgId(result.msg_id);
        jpushMsg.setAudience(JSON.toJSONString(resArray));
        jpushMsg.setPlatform("all");
        jpushMsg.setBody(JSON.toJSONString(vo));
        jpushMsg.setMessage(result.getOriginalContent());
        jpushMsg.setCreateTime(date);
        jpushMsgs.add(jpushMsg);

        JpushLog jpushLog = new JpushLog();
        jpushLog.setId(idWorker.nextId());
        jpushLog.setMsgId(msPri);
        jpushLog.setCreateTime(date);
        jpushLog.setEvent(event);
        jpushLog.setTaskId(taskId);
        jpushLog.setSendno(Long.valueOf(result.sendno));
        jpushLogs.add(jpushLog);
        jpushMsgDao.insertSelective(jpushMsg);
        jpushLogDao.insertSelective(jpushLog);
    }

    @Override
    public List<TaskDisplayVo> getPublishedList(Long userId, Long pageNo, Long pageSize) {
        //获取任务列表
        List<TaskDisplayVo> list = taskDao.getPublishedList(userId, pageNo, pageSize);
        if (!CollectionUtils.isEmpty(list)) {
            list = traversalTaskDisplayVo(list);
        }
        return list;
    }

    /**
     * 获取我的科室任务
     *
     * @param deptId   部门id
     * @param pageNo   页码
     * @param pageSize 条数
     * @return 我的科室任务列表
     */
    @Override
    public List<TaskDisplayVo> getDepartmentList(Long deptId, Long pageNo, Long pageSize) {
        //获取任务列表
        List<TaskDisplayVo> list = taskExecutionDao.getDepartmentList(deptId, pageNo, pageSize);
        if (!CollectionUtils.isEmpty(list)) {
            list = traversalTaskDisplayVo(list);
        }
        return list;
    }


    @Override
    public TaskStatisticsVo getStatistics(Long userId, Long deptId, Integer year, Integer month) {
        if (deptId != null) {
            userId = null;
        }
        LocalDate first = LocalDate.of(year, month, 1);
        LocalDate last = first.with(TemporalAdjusters.lastDayOfMonth());
        if (last.isAfter(LocalDate.now())) {
            last = LocalDate.now();
        }
        last = last.plusDays(1);
        Date firstDate = Date.from(first.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
        Date lastDate = Date.from(last.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
        long days = Period.between(first, last).getDays();
        TaskStatisticsVo statisticsVo = new TaskStatisticsVo();
        List<TaskStatisticsItemVo> trend = taskDao.selectDayStatistics(userId, deptId, firstDate, lastDate);
        for (int i = 0; i < days; i++) {
            String itemName = month + "-" + (i + 1);
            Optional<TaskStatisticsItemVo> op = trend.stream().filter(t -> t.getItemName().equals(itemName)).findFirst();
            if (!op.isPresent()) {
                TaskStatisticsItemVo vo = new TaskStatisticsItemVo();
                vo.setItemName(itemName);
                vo.setCount(0d);
                trend.add(i, vo);
            }
        }
        statisticsVo.setTrend(trend);
        List<TaskStatisticsItemVo> pieChart = taskDao.selectPercentStatistics(userId, deptId, firstDate, lastDate);
        double total = pieChart.stream().mapToDouble(value -> value.getCount()).sum();
        total = total > 0 ? total : 1;
        List<DataDictVo> taskTypes = userClient.listDataDict("00002");
        for (int i = 0; i < taskTypes.size(); i++) {
            DataDictVo dataDictVo = taskTypes.get(i);
            Optional<TaskStatisticsItemVo> op = pieChart.stream().filter(s -> s.getItemName().equals(dataDictVo.getCode())).findFirst();
            if (!op.isPresent()) {
                TaskStatisticsItemVo vo = new TaskStatisticsItemVo();
                vo.setItemName(dataDictVo.getValue());
                vo.setCount(0d);
                pieChart.add(i, vo);
            } else {
                TaskStatisticsItemVo vo = op.get();
                vo.setItemName(dataDictVo.getValue());
                vo.setCount(vo.getCount() / total);
            }
        }

        statisticsVo.setPieChart(pieChart);
        return statisticsVo;
    }

    @Override
    public List<SosDiseaseVo> getDisease(Long userId) {
        SosDiseaseExample example = new SosDiseaseExample();
        example.createCriteria().andValidEqualTo(1);
        List<SosDisease> list = sosDiseaseDao.selectByExample(example);
        List<SosDiseaseVo> diseaseVos = list.stream().map(d -> {
            SosDiseaseVo vo = new SosDiseaseVo();
            CachedBeanCopier.copy(d, vo);
            return vo;
        }).collect(Collectors.toList());

        return diseaseVos;
    }

    /**
     * 获取已接收任务:按任务类型区分
     *
     * @param userId   用户id
     * @param taskType 任务类型
     * @param pageNo   页码
     * @param pageSize 条数
     * @return 已经接收的各种任务类型的列表
     */
    @Override
    public List<TaskDisplayVo> getReceivedList(Long userId, String taskType, Long pageNo, Long pageSize) {
        UserDo user = userClient.getUser(userId);
        //任务列表
        List<TaskDisplayVo> list = taskExecutionDao.getReceivedList(userId, taskType, pageNo, pageSize, user.getType());
        if (!CollectionUtils.isEmpty(list)) {
            list = traversalTaskDisplayVo(list);
        }
        return list;
    }

    /**
     * 获取已发布任务:按任务类型区分
     *
     * @param userId   用户id
     * @param taskType 任务类型
     * @param pageNo   页码
     * @param pageSize 条数
     * @return 按任务类型区分的已发布任务列表
     */
    @Override
    public List<TaskDisplayVo> getReleasedList(Long userId, String taskType, Long pageNo, Long pageSize) {
        UserDo user = userClient.getUser(userId);
        //任务列表
        List<TaskDisplayVo> list = taskDao.getReleasedList(userId, taskType, pageNo, pageSize, user.getType());
        if (!CollectionUtils.isEmpty(list)) {
            list = traversalTaskDisplayVo(list);
        }
        return list;
    }

    /**
     * 获取任务统计数据
     *
     * @param type     搜索类型(1:接收; 2:发布)
     * @param userId   用户ID
     * @param dateTime 时间节点
     * @return
     */
    @Override
    public TaskCountResultVo getTaskCountResultVo(Integer type, Long userId, Date dateTime) {
        TaskCountResultVo taskCountResultVo = new TaskCountResultVo();
        if (2 == type) {
            List<TaskCountVo> zxfbList = taskDao.getTaskCountZXFB(userId, dateTime);
            taskCountResultVo.setTaskZXList(zxfbList);

            List<TaskCountVo> btfbList = taskDao.getTaskCountBTFB(userId, dateTime);
            taskCountResultVo.setTaskBTList(btfbList);
        } else if (1 == type) {
            List<TaskCountVo> zxjsList = taskDao.getTaskCountZXJS(userId, dateTime);
            taskCountResultVo.setTaskZXList(zxjsList);

            List<TaskCountVo> btjsList = taskDao.getTaskCountBTJS(userId, dateTime);
            taskCountResultVo.setTaskBTList(btjsList);
        }
        return taskCountResultVo;
    }

    /**
     * 获取各种类型的最新一条任务
     *
     * @param userId   用户id
     * @param taskType 任务类型
     * @return 一条该类型的最新任务
     */
    @Override
    public TaskDisplayVo getNewestTask(Long userId, String taskType) {
        TaskDisplayVo newestTask = taskExecutionDao.getNewestTask(userId, taskType);
        //任务附件
        if (!taskType.equals(TASK_TRANSF)) {
            List<TaskFileVo> fileVoList = taskFileDao.getListByTaskId(newestTask.getTaskId());
            if (!CollectionUtils.isEmpty(fileVoList)) {
                newestTask.setFiles(fileVoList);
            }
        }
        //交接
        List<TaskTransferVo> taskTransferVoList = taskTransferDao.getListByTaskId(newestTask.getTaskId());
        if (!CollectionUtils.isEmpty(taskTransferVoList)) {
            taskTransferVoList.stream().forEach(mm -> {
                //患者检测数据
                List<TaskPatientDataVo> taskPatientDataVoList = patientDataDao.getListByTaskId(newestTask.getTaskId());
                if (!CollectionUtils.isEmpty(taskPatientDataVoList)) {
                    mm.setPatientDatas(taskPatientDataVoList);
                }
                //交接附件
                List<TaskFileVo> taskFileVoList = taskFileDao.getListByTaskId(newestTask.getTaskId());
                if (!CollectionUtils.isEmpty(taskFileVoList)) {
                    mm.setFiles(taskFileVoList);
                }
            });
            newestTask.setTransfers(taskTransferVoList);
        }
        //sos
        TaskSosVo taskSosVo = taskSOSDao.selectSosByTaskId(newestTask.getTaskId());
        if (!StringUtils.isEmpty(taskSosVo)) {
            newestTask.setSos(taskSosVo);
        }
        return newestTask;
    }

    /**
     * 首页按类型区分的最新任务、未确认数量
     *
     * @param userId 用户id
     * @return 各种类型的最新任务、未确认数量
     */
    @Override
    public TaskAndConfirmStatusVo getNewestTaskAndStatus(Long userId) {
        UserDo user = userClient.getUser(userId);

        TaskAndConfirmStatusVo taskAndConfirmStatusVo = new TaskAndConfirmStatusVo();
        //未确认数量
        List<TaskConfirmStatusVo> confirmStatus = taskExecutionDao.getConfirmStatus(userId);
        taskAndConfirmStatusVo.setConfirmStatusVos(confirmStatus);

        //最新任务
        List<TaskDisplayVo> list = new ArrayList<>();
        //任务类型
        String parentCode = "00002";
        List<DataDictVo> dataDictVos = userClient.listDataDict(parentCode);
        if (!CollectionUtils.isEmpty(dataDictVos)) {
            dataDictVos.stream().forEach(item -> {
                TaskDisplayVo newestTask = taskExecutionDao.getNewestTask(userId, item.getCode());
                if (null != newestTask) {
                    //任务附件
                    if (!item.getCode().equals(TASK_TRANSF)) {
                        List<TaskFileVo> fileVoList = taskFileDao.getListByTaskId(newestTask.getTaskId());
                        if (!CollectionUtils.isEmpty(fileVoList)) {
                            newestTask.setFiles(fileVoList);
                        }
                    }
                    //交接
                    List<TaskTransferVo> taskTransferVoList = taskTransferDao.getListByTaskId(newestTask.getTaskId());
                    if (!CollectionUtils.isEmpty(taskTransferVoList)) {
                        taskTransferVoList.stream().forEach(mm -> {
                            //患者检测数据
                            List<TaskPatientDataVo> taskPatientDataVoList = patientDataDao.getTransferById(mm.getTransferId());
                            if (!CollectionUtils.isEmpty(taskPatientDataVoList)) {
                                mm.setPatientDatas(taskPatientDataVoList);
                            }
                            //交接附件
                            List<TaskFileVo> taskFileVoList = taskFileDao.getTransferFileList(newestTask.getTaskId(), mm.getTransferId());
                            if (!CollectionUtils.isEmpty(taskFileVoList)) {
                                mm.setFiles(taskFileVoList);
                            }
                        });
                        newestTask.setTransfers(taskTransferVoList);
                    }
                    //sos
                    TaskSosVo taskSosVo = taskSOSDao.selectSosByTaskId(newestTask.getTaskId());
                    if (!StringUtils.isEmpty(taskSosVo)) {
                        newestTask.setSos(taskSosVo);
                    }
                    list.add(newestTask);
                }
            });
            taskAndConfirmStatusVo.setDisplayVos(list);
        }
        return taskAndConfirmStatusVo;
    }

    /**
     * 搜索任务
     *
     * @param userId     用户id
     * @param searchName 发布人&内容 搜索
     * @param taskType   任务类型
     * @param type       搜索类型(1:接收; 2:发布)
     * @param pageNo     页码
     * @param pageSize   条数
     * @return
     */
    @Override
    public List<TaskDisplayVo> getSearchTaskList(Long userId, String searchName, String taskType, Integer type, Long pageNo, Long pageSize) {
        List<TaskDisplayVo> list = taskDao.getSearchTaskList(userId, searchName, taskType, type, pageNo, pageSize);
        if (!CollectionUtils.isEmpty(list)) {
            list = traversalTaskDisplayVo(list);
        }
        return list;
    }

    /**
     * 循环任务列表,增加任务附件,交接,sos
     *
     * @param list
     * @return
     */
    private List<TaskDisplayVo> traversalTaskDisplayVo(List<TaskDisplayVo> list) {
        list.stream().forEach(item -> {
            //任务附件
            if (!item.getTaskType().equals(TASK_TRANSF)) {
                List<TaskFileVo> fileVoList = taskFileDao.getListByTaskId(item.getTaskId());
                if (!CollectionUtils.isEmpty(fileVoList)) {
                    item.setFiles(fileVoList);
                }
            }
            //交接
            List<TaskTransferVo> taskTransferVoList = taskTransferDao.getListByTaskId(item.getTaskId());
            if (!CollectionUtils.isEmpty(taskTransferVoList)) {
                taskTransferVoList.stream().forEach(mm -> {
                    //患者检测数据
                    List<TaskPatientDataVo> taskPatientDataVoList = patientDataDao.getTransferById(mm.getTransferId());
                    if (!CollectionUtils.isEmpty(taskPatientDataVoList)) {
                        mm.setPatientDatas(taskPatientDataVoList);
                    }
                    //交接附件
                    List<TaskFileVo> taskFileVoList = taskFileDao.getTransferFileList(item.getTaskId(), mm.getTransferId());
                    if (!CollectionUtils.isEmpty(taskFileVoList)) {
                        mm.setFiles(taskFileVoList);
                    }
                });
                item.setTransfers(taskTransferVoList);
            }
            //sos
            TaskSosVo taskSosVo = taskSOSDao.selectSosByTaskId(item.getTaskId());
            if (!StringUtils.isEmpty(taskSosVo)) {
                item.setSos(taskSosVo);
            }

            TaskAmbulanceVo taskAmbulanceVo = remindAmbulanceDao.getTaskAmbulanceVo(item.getTaskId());
            if (!StringUtils.isEmpty(taskAmbulanceVo)) {
                item.setTaskAmbulanceVo(taskAmbulanceVo);
            }

            List<TaskUserVo> taskUserVoList = taskDao.getTaskUserVoList(item.getTaskId());
            if (!CollectionUtil.isEmpty(taskUserVoList)) {
                item.setTaskUserVoList(taskUserVoList);
            }
        });

        return list;
    }

    /**
     * sos定时任务
     */
    @Override
    public void timeSosTask() throws BaseException {
        long time = System.currentTimeMillis() - TASK_TIME;
        List<TaskExecution> taskExecutionList = taskExecutionDao.getTimeSosTask();

        for (TaskExecution taskExecution : taskExecutionList) {
            TaskTime taskTime = taskTimeDao.selectByPrimaryKey(taskExecution.getTaskTimeId());
            if (taskTime.getTaskTime() > time) {
                continue;
            }
            List<DataDictVo> dataDictVos = userClient.listDataDict("SOS_FORWARD");
            if (dataDictVos.get(0).getParentCode().equals("1") && taskTime.getVersion() < 3) {
                TaskSOS taskSOS = taskSOSDao.selectByTaskId(taskExecution.getTaskId(), null, null);
                //修改状态
                taskExecution.setConfirmStatus("0000800005");
                taskExecution.setConfirmTime(new Date());
                log.info("**********************************************sos定时任务开始***********************************************");
                taskExecutionDao.updateByPrimaryKey(taskExecution);
                log.info("更新sos任务状态：{} ,状态：{}", taskExecution.getTaskId(), "0000800005");
                log.info("**********************************************sos定时任务结束***********************************************");


                TaskSosDto taskSosDto = new TaskSosDto();
                taskSosDto.setLatitude(taskSOS.getLatitude());
                taskSosDto.setAddress(taskSOS.getUserAddress());
                taskSosDto.setDiagnosis(taskSOS.getRemark());
                taskSosDto.setLongitude(taskSOS.getLongitude());
                taskSosDto.setSenderId(taskSOS.getUserId());
                taskSosDto.setDiagnosis(taskSOS.getRemark());
                SOSForward(taskSosDto, taskTime.getVersion() + 1, taskExecution);
            } else {
                //修改状态
                taskExecution.setConfirmStatus("0000800010");
                taskExecution.setConfirmTime(new Date());
                log.info("**********************************************sos定时任务开始***********************************************");
                taskExecutionDao.updateByPrimaryKey(taskExecution);
                log.info("更新sos任务状态：{} ,状态：{}", taskExecution.getTaskId(), "0000800010");
                log.info("**********************************************sos定时任务结束***********************************************");
                //发短信通知
                TaskSosVo taskSosVo = taskSOSDao.selectSosByTaskId(taskExecution.getTaskId());
                try {
                    Map<String, String> map = new HashMap<>();
                    map.put("status", "暂无医院接收");
                    map.put("msg", "请立即拨打120");
                    //JSMSUtil.sendTempSMS(taskSosVo.getPatientMobile(), 0, map);
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }

        }
    }

    /**
     * 获取对应的sos任务ID
     *
     * @param taskId 出诊任务ID
     * @param userId 用户ID
     * @return
     */
    @Override
    public Long getSosTaskId(Long taskId, Long userId) {
        return taskExecutionDao.getSosTaskId(taskId, userId);
    }

    /**
     * sos 上报位置
     *
     * @param taskId
     * @param longitude
     * @param latitude
     */
    @Override
    public Long sosReportLocation(Long userId, Long taskId, BigDecimal longitude, BigDecimal latitude) {
        SosPositionRecordVo sosPositionRecordVo = new SosPositionRecordVo();
        sosPositionRecordVo.setId(idWorker.nextId());
        sosPositionRecordVo.setTaskId(taskId);
        sosPositionRecordVo.setLatitude(latitude);
        sosPositionRecordVo.setLongitude(longitude);
        sosPositionRecordVo.setCreateTime(new Date());
        Long aLong = sosPositionRecordDao.insertSelective(sosPositionRecordVo);

        SosReceiverDo SosReceiverDo = new SosReceiverDo();
        SosReceiverDo.setUserId(userId);
        SosReceiverDo.setLatitude(latitude);
        SosReceiverDo.setLongitude(longitude);
        sosReceiverDao.updateByUserId(SosReceiverDo);
        List<TaskExecution> taskExecutionVisit = taskExecutionDao.getTaskExecutionVisit(taskId);
        for (TaskExecution taskExecution : taskExecutionVisit) {
            if (taskExecution.getReportLocation() == 1) {
                RemindAmbulanceVo remindAmbulanceVo = remindAmbulanceDao.getAmbulanceVoByTaskId(taskExecution.getTaskId());
                remindAmbulanceVo.setTaskStatus(1);
                remindAmbulanceVo.setLatitude(latitude);
                remindAmbulanceVo.setLongitude(longitude);
                remindAmbulanceDao.updateByPrimaryKeySelective(remindAmbulanceVo);
            }
        }
        return aLong;
    }

    /**
     * 转发sos任务
     *
     * @param taskSosDto
     * @return
     */
    private void SOSForward(TaskSosDto taskSosDto, Long version, TaskExecution taskExecutionOld) throws BaseException {
        List<TaskExecutionDept> execDepts = new ArrayList<>();
        List<TaskExecution> executions = new ArrayList<>();
        //发布人id
        Long senderId = taskSosDto.getSenderId();
        TaskSOSStatusVo status = this.getSOSTaskStatusByPatientId(senderId, null);
        if (status != null && "0000800001|0000800002|0000800003|0000800004|0000800010|0000800011|0000800012".contains(status.getConfirmStatus())) {
            throw new BaseRuntimeException(ServerStatusEnum.SOS_NOT_COMPLETE);
        }
        UserDo sender = userClient.getUser(senderId);
        @NotNull BigDecimal longitude = taskSosDto.getLongitude();
        @NotNull BigDecimal latitude = taskSosDto.getLatitude();

        //插入任务
        Long taskId = idWorker.nextId();
        Task task = new Task();
        String taskType = "0000200001";
        task.setTaskId(taskId);//任务表id
        Date date = new Date();
        task.setCreateTime(date);//创建时间
        task.setUpdateTime(date);//修改时间
        task.setTaskType(taskType);//任务类型
        task.setSenderName(sender.getName());//发布人姓名
        task.setSenderId(senderId);//发布人id
        task.setPriority("0000300003");//紧急程度
        task.setConfirmRequired(0);//是否需要确认
        task.setVersion(version);

        //插入任务时间
        Long timeId = idWorker.nextId();//时间id
        TaskTime taskTime = new TaskTime();
        taskTime.setId(timeId);
        taskTime.setTaskId(taskId);//任务id
        taskTime.setTaskTime(date.getTime());//任务时间
        taskTime.setTimeType("0000400001");//时间类型
        taskTime.setEndTime(date);
        taskTime.setCycleCount(1);//默认1
        taskTime.setCycleType("-1");//周期类型
        taskTime.setDelFlag(0);//未删除
        taskTime.setVersion(version);//版本号

        List<HospitalVo> hospitals = userClient.listHospitalsByUser(senderId, longitude, latitude, "");
        HospitalVo hospital = null; //userClient.getHospitalById(wxApp.getHospitalId());
        /*if (null == hospital) {
            throw new BaseRuntimeException(ServerStatusEnum.NO_SOS_HOSPITAL);
        }*/
        UserSimpleVo doctor = null;
        int size = Integer.parseInt(version + "") - 1;
        for (int i = size; i < hospitals.size(); i++) {
            hospital = hospitals.get(i);
            log.info("转发至医院id：" + hospital.getHospitalId() + ", 名称：" + hospital.getHospitalName() + "=============================================i=" + i);
            List<UserSimpleVo> doctors = userClient.listHospitalSOSDoctor(hospital.getHospitalId(), null, taskType);
            if (!CollectionUtils.isEmpty(doctors)) {
                doctor = doctors.get(0);
                break;
            } else {
                log.info("医院id：" + hospital.getHospitalId() + ", 名称：" + hospital.getHospitalName() + "目前无SOS正在值班的接诊医生");
                if (i == hospitals.size() - 1) {
                    //修改状态
                    taskExecutionOld.setConfirmStatus("0000800010");
                    taskExecutionOld.setConfirmTime(new Date());
                    taskExecutionDao.updateByPrimaryKey(taskExecutionOld);
                    log.info("更新sos任务状态：{} ,状态：{}", taskExecutionOld.getTaskId(), "0000800010");
                    return;
                }
            }
        }

        //执行记录
        Long receiverId = doctor.getUserId();//只根据医院id 查询的接收者
        Long execId = idWorker.nextId();
        this.addReceiverToList(executions, taskId, date, timeId, date, receiverId, doctor.getName(), execId, taskType);

        //接受者部门
        List<UserDeptDto> receiverDeptDtos = userClient.listSupperDeptByUserId(receiverId);
        this.addReceiverDeptToList(execDepts, receiverDeptDtos, execId);

        //发送者部门
        List<UserDeptDto> senderDeptDtos = receiverDeptDtos;
        List<TaskSenderDept> senderDepts = this.getSenderDeptList(taskId, senderDeptDtos);
        //腾讯经纬度转换为百度经纬度
        Map<String, Double> map = mapConvertUtil.map_tx2bd(latitude.doubleValue(), longitude.doubleValue());
        //SOS位置
        Long taskSosDoId = idWorker.nextId();
        TaskSOS taskSOS = new TaskSOS();
        taskSOS.setId(taskSosDoId);//taskId
        taskSOS.setTaskId(taskId);//任务id
        taskSOS.setHospitalId(hospital.getHospitalId());
        taskSOS.setHospitalName(hospital.getHospitalName());
        taskSOS.setHospitalLongitude(hospital.getLongitude());
        taskSOS.setHospitalLatitude(hospital.getLatitude());
        taskSOS.setUserAddress(taskSosDto.getAddress());
        taskSOS.setUserId(taskSosDto.getSenderId());
        taskSOS.setPatientName(sender.getName());
        taskSOS.setPatientMobile(sender.getMobile());
        taskSOS.setLongitude(new BigDecimal(map.get("lng") + ""));
        taskSOS.setLatitude(new BigDecimal(map.get("lat") + ""));
        taskSOS.setRemark(taskSosDto.getDiagnosis());
        taskSOS.setCreateTime(new Date());
        //增加医院ID
        task.setHospitalId(hospital.getHospitalId());

        //紧急联系人
        UserEmergencyContactVo contact = userClient.getContact(senderId);
        if (contact != null) {
            taskSOS.setEmergencyId(contact.getId());
            taskSOS.setEmergencyRelationship(contact.getRelationship());
            taskSOS.setEmergencyMobile(contact.getMobile());
            taskSOS.setEmergencyName(contact.getName());
        } else {
            log.info("患者用户id:" + senderId + ",姓名：" + sender.getName() + "，无紧急联系人");
        }

        taskDao.insert(task);
        taskSOSDao.insertSelective(taskSOS);
        taskTimeDao.insertSelective(taskTime);
        taskExecutionDao.insertBatch(executions);
        taskSenderDeptDao.insertBatch(senderDepts);
        taskExecutionDeptDao.insertBatch(execDepts);
    }

    /**
     * 获取医院救护车位置
     *
     * @param hospitalId 医院id
     * @return
     */
    @Override
    public List<SosPlatformVo> sosAmbulanceLocation(Long hospitalId) {
        return sosReceiverDao.sosAmbulanceLocation(hospitalId);
    }

    /**
     * 推送短信消息
     *
     * @return
     */
    @Override
    public void pushSMSNotice() {
        long time = System.currentTimeMillis();
        List<TaskExecution> taskExecutionList = taskExecutionDao.getTimeTask();
        for (TaskExecution taskExecution : taskExecutionList) {
            TaskTime taskTime = taskTimeDao.selectByPrimaryKey(taskExecution.getTaskTimeId());
            if (time - taskTime.getTaskTime() < TASK_SMS_TIME || time - taskTime.getTaskTime() > TASK_SMS_TIME + 10000) {
                continue;
            }

            //发短信通知
            UserDo user = userClient.getUser(taskExecution.getReceiverId());
            HospitalVo hospitalVo = userClient.getHospitalById(user.getHospitalId());

            Map<String, String> map = new HashMap<>();
            map.put("task_type", TaskEnum.getByCode(taskExecution.getTaskType()).value);
            map.put("date_time", DateFormatUtils.format(taskTime.getTaskTime(), "yyyy-MM-dd HH:mm:ss"));
            if (!"0000200001".equals(taskExecution.getTaskType())) {
                log.info("**********************************************推送短信消息任务开始****************短信*******************************");
                JSMSUtil.sendTempSMS(user.getMobile(), 184550, map);
                log.info("**********************************************推送短信消息任务结束*****************短信******************************");
            } else {
                try {
                    if (hospitalVo.getNoticeType() == 1) {
                        log.info("**********************************************推送短信消息任务开始****************短信*******************************");
                        JSMSUtil.sendTempSMS(user.getMobile(), 184550, map);
                        log.info("**********************************************推送短信消息任务结束*****************短信******************************");
                    } else if (hospitalVo.getNoticeType() == 2) {
                        log.info("**********************************************推送短信消息任务开始****************语音*******************************");
                        TXVoiceUtil.SendTtsVoice(user.getMobile(), "839897");
                        log.info("**********************************************推送短信消息任务结束*****************语音******************************");
                    } else if (hospitalVo.getNoticeType() == 3) {
                        log.info("**********************************************推送短信消息任务开始****************语音+短信*******************************");
                        TXVoiceUtil.SendTtsVoice(user.getMobile(), "839897");
                        JSMSUtil.sendTempSMS(user.getMobile(), 184550, map);
                        log.info("**********************************************推送短信消息任务结束*****************语音+短信******************************");

                    }
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }

        }
    }

    /**
     * 获取车辆列表
     *
     * @return
     */
    @Override
    public List<RemindAmbulanceVo> getAmbulanceVoList(Long hospitalId) {
        return remindAmbulanceDao.getAmbulanceVoList(hospitalId);
    }

    /**
     * 增加任务车辆记录
     *
     * @return
     */
    @Override
    public TaskStatusUpdateVo saveTaskAmbulance(Long userId, Long taskId, Long ambulanceId, String confirmStatus) throws BaseException {
        UserDo user = userClient.getUser(userId);
        if (ambulanceId > 0) {
            RemindAmbulanceVo ambulanceVo = remindAmbulanceDao.getAmbulanceVo(ambulanceId, "", "");
            if (null == ambulanceVo) {
                throw new BaseRuntimeException(ServerStatusEnum.TASK_AMBULANCE_NULL);
            }
            TaskAmbulanceVo taskAmbulanceVo = new TaskAmbulanceVo();
            taskAmbulanceVo.setTaskAmbulanceId(idWorker.nextId());
            taskAmbulanceVo.setAmbulanceId(ambulanceVo.getAmbulanceId());
            taskAmbulanceVo.setCarNumber(ambulanceVo.getCarNumber());
            taskAmbulanceVo.setHospitalId(ambulanceVo.getHospitalId());
            taskAmbulanceVo.setTaskId(taskId);
            taskAmbulanceVo.setCreateTime(new Date());
            taskAmbulanceVo.setCreateUser(userId);
            remindAmbulanceDao.saveTaskAmbulance(taskAmbulanceVo);
        }
        return updateStatus(userId, taskId, confirmStatus);
    }

    /**
     * 保存车辆位置信息
     *
     * @return
     */
    @Override
    public void saveAmbulancePosition() throws IOException {
        String accessToken;
        Object object = redisUtil.get("signature");
        if (null != object) {
            JSONObject obj = JSONObject.parseObject(object.toString());
            accessToken = obj.getString("accessToken");
        } else {
            accessToken = CarGpsUtil.getAccessToken();
            redisUtil.set("signature", accessToken, 100 * 60);
        }

        JSONObject jsonObject = CarGpsUtil.getPosition(accessToken);
        if (null != jsonObject && jsonObject.getInteger("code") == 0) {
            JSONArray jsonArray = jsonObject.getJSONArray("data");
            for (Object obj : jsonArray) {
                log.info("**********************************************车辆位置信息任务开始***********************************************");
                JSONObject jb = (JSONObject) obj;
                log.error(jb.getString("imei"));
                log.error(jb.getDouble("lat").toString());
                log.error(jb.getDouble("lng").toString());
                double[] doubles = MapConvertUtil.gps84_To_bd09(jb.getDouble("lat"), jb.getDouble("lng"));
                RemindAmbulanceVo ambulanceVo = remindAmbulanceDao.getAmbulanceVo(null, "", jb.getString("imei"));
                if (null != ambulanceVo) {
                    ambulanceVo.setLatitude(new BigDecimal(String.valueOf(doubles[0])));
                    ambulanceVo.setLongitude(new BigDecimal(String.valueOf(doubles[1])));
                    remindAmbulanceDao.updateByPrimaryKeySelective(ambulanceVo);
                    if (1 == ambulanceVo.getTaskStatus()) {
                        SosPositionRecordVo sosPositionRecordVo = new SosPositionRecordVo();
                        sosPositionRecordVo.setId(idWorker.nextId());
                        sosPositionRecordVo.setAmbulanceId(ambulanceVo.getAmbulanceId());
                        sosPositionRecordVo.setLatitude(new BigDecimal(String.valueOf(doubles[0])));
                        sosPositionRecordVo.setLongitude(new BigDecimal(String.valueOf(doubles[1])));
                        sosPositionRecordVo.setCreateTime(new Date());
                        sosPositionRecordDao.insertSelective(sosPositionRecordVo);
                    }
                }
                log.info("**********************************************车辆位置信息任务结束***********************************************");
            }
        }

    }

    /**
     * 发送视频请求
     *
     * @param taskId 任务id
     * @return
     */
    @Override
    public int updateReportVideoTask(@Param(value = "taskId") Long taskId, @Param("userId") Long userId, @Param(value = "videoStatus") Integer videoStatus) {
        TaskExecution taskExecution = taskExecutionDao.getTaskExecution(taskId, userId);
        if (taskExecution == null) {
            throw new BaseRuntimeException(ServerStatusEnum.TASK_NOT_EXIST);
        }
        taskExecution.setReportVideo(videoStatus);
        return taskExecutionDao.updateByPrimaryKeySelective(taskExecution);
    }
}
